﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using CityLife.GameLogic;
using System.Collections.Generic;
using System.Reflection;

namespace CityLife.Objects
{
    public class Car : Canvas
    {
       // System.Windows.Threading.DispatcherTimer myDispatcherTimer = null;



        public Direction Direction = Direction.Right;
        public CityCanvas CityCanvas;
        UserControl cube;

        public int GlobalPixelCounter = 0;
        public Car()
	    {
 
            this.Width = 30;
            this.Height = 30;

            int model = Convert.ToInt32( new Random().Next(1,3));
            cube = (UserControl)Assembly.GetExecutingAssembly().CreateInstance("CityLife.Car" + model.ToString());
            
			
           // cube = new CityLife.Car10();
            History = new List<Direction>();       

            this.Children.Add(cube);

            
           // Drive();
            //myDispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            //myDispatcherTimer.Interval = TimeSpan.FromMilliseconds(100 / MainPage.Heart.CityInterval);
            //myDispatcherTimer.Tick += new EventHandler(myDispatcherTimer_Tick);
            //myDispatcherTimer.Start();

            
	    }

        void Heart_CityIntervalChanged(object sender, EventArgs e)
        {
            //myDispatcherTimer.Stop();
            //// Drive();
            //myDispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            //myDispatcherTimer.Interval = TimeSpan.FromMilliseconds(100/ MainPage.Heart.CityInterval);
            //myDispatcherTimer.Tick += new EventHandler(myDispatcherTimer_Tick);
            //myDispatcherTimer.Start();
        }




        //void myDispatcherTimer_Tick(object sender, EventArgs e)
        //{
        //    Drive();
        //}

        public void Drive()
        {
           // double X = (double)this.GetValue(Canvas.LeftProperty);
           // double Y = (double)this.GetValue(Canvas.TopProperty);

            double xx = (double)this.GetValue(Canvas.LeftProperty);
            double yy = (double)this.GetValue(Canvas.TopProperty);

            if (GlobalPixelCounter == 0)
            {
                GlobalPixelCounter = 30;

                GeneralTransform generalTransform = (cube as UIElement).TransformToVisual(Application.Current.RootVisual);
                Point pnts = generalTransform.Transform(new Point(1,1));
                Point pnts2 = generalTransform.Transform(new Point(25, 25));
                Rect areaInAbsoluteCoordinates = new Rect(pnts, pnts2);

                //Rectangle r = new Rectangle();
                //r.Fill = new SolidColorBrush(Colors.Cyan);
                //r.SetValue(Canvas.LeftProperty, areaInAbsoluteCoordinates.Left);
                //r.SetValue(Canvas.TopProperty, areaInAbsoluteCoordinates.Top);

                //r.Width = areaInAbsoluteCoordinates.Width;
                //r.Height = areaInAbsoluteCoordinates.Height;
                //CityCanvas.GlobalCanvas.Children.Add(r);

                IEnumerable<UIElement> childrenInArea = VisualTreeHelper.FindElementsInHostCoordinates(areaInAbsoluteCoordinates, (this.Parent as Canvas));

                foreach (UIElement element in childrenInArea)
                {
                    if (element is Canvas)
                        if ((element as Canvas).Tag != null && (element as Canvas).Tag.ToString() == "ROAD")
                        {
                            //(element as Canvas).Opacity = 0.5;
                            Zone z = element as Zone;
                            if (z != null && z.ZoneDirections.Count > 0)
                            {
                                List<Direction> directions = z.ZoneDirections;

                                if (z.ConnectionID > 0)
                                {
                                   // Remove the neighbour direction - SocketAddress the car will not leave the screen

                                    if(z.GridColumn==0)
                                        directions.Remove(Direction.Left);

                                         if(z.GridColumn == 19)
                                    directions.Remove(Direction.Right);

                                          if(z.GridRow==0)
                                              directions.Remove(Direction.Top);

                                                if(z.GridRow==19)
                                                    directions.Remove(Direction.Bottom);



                                }


                                //select non opposite available direction
                                this.Direction = getUniquePosition(directions);
 

                                      //Storyboard story = new Storyboard();
                                      //DoubleAnimation pa = new DoubleAnimation();
                     
                                      //pa.RepeatBehavior  = new RepeatBehavior(1);

                                      //pa.Duration = new Duration(TimeSpan.FromMilliseconds(MainPage.Heart.CityInterval * 1000));
                                
                                      //pa.From = pnts.X;
                                      //pa.To = pnts2.X;
                                  
                                   
                                      //PropertyPath p = new PropertyPath(Canvas.TopProperty);

                                      //story.Children.Add(pa);
                                      //Storyboard.SetTarget(pa, this);
                                      //Storyboard.SetTargetProperty(pa, p);

                                      //story.Completed += new EventHandler(story_Completed);
                                      //story.Begin();

                                break;
                                     
                             }
                        }
                }
            }

             GlobalPixelCounter--;
       

            switch(this.Direction)
            {
                case Direction.Bottom:
                    this.SetValue(Canvas.TopProperty, yy + 1);
                    break;
                case Direction.Top:
                    this.SetValue(Canvas.TopProperty,yy - 1);
                    break;
                case Direction.Left:
                    this.SetValue(Canvas.LeftProperty, xx - 1);
                    break;
                case Direction.Right:
                    this.SetValue(Canvas.LeftProperty,xx + 1);
                    break;

            }

      
 
        }

  


        public Direction getUniquePosition(List<Direction> orgDirections)
        {
            List<Direction> directions =new List<Direction>( orgDirections);
             
            Direction dir = this.Direction;

            Direction selectedDir = Direction.None;
            //handle turns differently then normal driving
            if (directions.Count > 1)
                directions.Remove(getOppositeDirection(this.Direction));


            if (directions.Count == 1)
            {
                selectedDir = directions[0];
                dir = selectedDir;
            }

            if (selectedDir == Direction.None)
            {

           

                Random random = new Random();
                int num = random.Next(directions.Count);

                dir = directions[num];
            }


            (cube as ICar).DoTurn(dir);

                   


                    //RotateTransform rt = new RotateTransform();
                    //tg.Children.Add(rt);
                    //rt.Angle = 270;
                    //rt.CenterX = 15;
                    //rt.CenterY = 15;
                    //cube.RenderTransform = tg;

               
 
          //  if (getOppositeDirection(this.Direction) != dir && directions.Count>1)
             //   return directions[num];

            return dir;

        //    return getUniquePosition(directions);       


  //foreach (Direction dir in z.ZoneDirections)
                                //{

                                //    //handle turns differently then normal driving
                                //    if( ((this.Direction == Direction.Left || this.Direction == Direction.Right) &&
                                //        (dir == Direction.Bottom || dir == Direction.Top))

                                //        ||

                                //        ((this.Direction == Direction.Bottom || this.Direction == Direction.Top) &&
                                //        (dir == Direction.Left || dir == Direction.Right)))
                                //    {
                                //        if (History.Count > 3)
                                //            History.RemoveAt(0);

                                //        selectedDir = getUniquePosition(z.ZoneDirections, dir);

                                //        if (!this.History.Contains(dir))
                                //        {
                                //            selectedDir = dir;

                                //        }
                                //        else
                                //        {
                                //            if (z.ZoneDirections.Count == 2)
                                //            {
                                //                selectedDir = dir;
                                //            }
                                //        }


                                //        History.Add(dir);
                                //    }



                                    //if (getOppositeDirection(this.Direction) != dir)
                                    //    selectedDir = dir;

        }

        public Direction getOppositeDirection(Direction dir)
        {
            if (dir == Direction.Bottom)
                return Direction.Top;

            if (dir == Direction.Top)
                return Direction.Bottom;

            if (dir == Direction.Left)
                return Direction.Right;

            if (dir == Direction.Right)
                return Direction.Left;


            return Direction.Bottom;
        }



        public List<Direction> History;
             
    }




    public enum Direction
    {
        Top,
        Right,
        Bottom,
        Left,
        None

    }
}
